﻿using Microsoft.VisualBasic.FileIO;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Bcpg;
using System.Diagnostics;
using System.ComponentModel;
using System.Windows.Threading;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Controls.Primitives;
using System.Collections.ObjectModel;
using Org.BouncyCastle.Utilities;

namespace Fire_Phone
{
    public partial class MainWindow : Window
    {
        /// <summary>
        /// 用于标记打开通讯录文件时通讯录名称是否出现错误
        /// </summary>
        Boolean Address_Book_Has_Error = false;
        /// <summary>
        /// 用于标记绑定通讯录文件时通讯录名称是否出现错误
        /// </summary>
        bool Address_Book_Bling_Error = false;
        public MainWindow()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 通讯录数量
        /// </summary>
        private int AddressBook_Number = 0;
        private void Windows_Loaded(object sender, RoutedEventArgs e)
        {

        }
        #region -- 菜单功能

        /// <summary>
        /// 打开的文件
        /// </summary>
        private string openyztfile_path = string.Empty;
        #region -- 文件
        /// <summary>
        /// 新建Yzt文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NewCrateYztFile_Click(object sender, RoutedEventArgs e)
        {
            // 弹出“另存为”对话框让用户选择保存位置和输入文件名
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Yzt Files (*.yzt)|*.yzt|All files (*.*)|*.*";
            bool? result = saveFileDialog.ShowDialog();

            PublicFunction publicfunction = new PublicFunction();
            if (result == true)
            {
                string filePath = saveFileDialog.FileName;

                // 检查扩展名是否正确，如果不正确则添加.yzt扩展名
                if (!filePath.EndsWith(".yzt", StringComparison.OrdinalIgnoreCase))
                {
                    filePath += ".yzt";
                }
                // 检查文件名是否符合限制条件
                string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(filePath);
                DirectoryInfo Address_Book = new DirectoryInfo(fileNameWithoutExtension);

                for (byte i = 0; i < Address_Book.Name.Length; i++)
                {
                    if (!publicfunction.IsGB2312(Address_Book.Name.Substring(i, 1), true))
                    {
                        MessageBox.Show("输入地址中第" + (i + 1).ToString() + "位存在超出GB2312字符集的字符，请更换地址名称", "输入地址字符限制提示");
                        Address_Book_Has_Error = true;
                    }
                }
                /*判断用户输入的地址是否存在超过限制的情况，最多有16个字节限制*/
                if (publicfunction.AddressBook_Name_CharNum > 16)
                {
                    MessageBox.Show("输入通讯录文件名文本过长，请将地址长度限定在8个汉字以内", "输入通讯录文件名字符长度限制提示");
                    Address_Book_Has_Error = true;
                }
                publicfunction.AddressBook_Name_CharNum = 0;                //处理完毕，开始重新用户名中的字符数  
                // 创建并打开新文件以进行写入
                try
                {
                    if (!Address_Book_Has_Error)
                    {
                        using (StreamWriter stream = new StreamWriter(filePath, false, Encoding.GetEncoding("GB2312")))
                        {
                            for (int i = 0; i < 127; i++)
                            {
                                stream.WriteLine(" " + "\t" + " " + "\n");
                            }
                        }
                        (DataTable dataTable, int rowCount) = ReadYztFileToDataTable(filePath);
                        if (dataTable != null)
                        {
                            DataQuery_vDataBinding(dataTable);
                            CountNonEmptyRows(dataTable);
                            CunrrentFileName_Text.Text = System.IO.Path.GetFileName(filePath);
                        }
                        else
                        {
                            MessageBox.Show("无法从文件中读取数据或文件格式不正确");
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"无法创建文件：{ex.Message}");
                }
                //标记复位
                Address_Book_Has_Error = false;
                openyztfile_path = filePath;
            }
        }
        /// <summary>
        /// 打开Yzt文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenYztFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Yzt Files (*.yzt)|*.yzt|All files (*.*)|*.*";

            PublicFunction publicfunction = new PublicFunction();
            if (openFileDialog.ShowDialog() == true)
            {
                openyztfile_path = openFileDialog.FileName;

                // 检查文件名是否符合限制条件
                string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(openyztfile_path);
                DirectoryInfo Address_Book = new DirectoryInfo(fileNameWithoutExtension);

                for (byte i = 0; i < Address_Book.Name.Length; i++)
                {
                    if (!publicfunction.IsGB2312(Address_Book.Name.Substring(i, 1), true))
                    {
                        MessageBox.Show("输入地址中第" + (i + 1).ToString() + "位存在超出GB2312字符集的字符，请更换地址名称", "输入地址字符限制提示");
                        Address_Book_Has_Error = true;
                    }
                }
                /*判断用户输入的地址是否存在超过限制的情况，最多有16个字节限制*/
                if (publicfunction.AddressBook_Name_CharNum > 16)
                {
                    MessageBox.Show("输入通讯录文件名文本过长，请将地址长度限定在8个汉字以内", "输入通讯录文件名字符长度限制提示");
                    Address_Book_Has_Error = true;
                }
                publicfunction.AddressBook_Name_CharNum = 0;                //处理完毕，开始重新用户名中的字符数 
                if (!Address_Book_Has_Error)
                {
                    DataTable dataTable = new DataTable();
                    (dataTable, int rowCount) = ReadYztFileToDataTable(openyztfile_path);
                    if (dataTable != null)
                    {
                        //DtgData.HeadersVisibility = DataGridHeadersVisibility.None;
                        DataQuery_vDataBinding(dataTable);
                        if (!Address_Book_Bling_Error)
                        {
                            CountNonEmptyRows(dataTable);
                            CunrrentFileName_Text.Text = System.IO.Path.GetFileName(openyztfile_path);
                        }
                        else
                        {
                            MessageBox.Show("导入的文件不符合通讯录文件要求（最多2列），请重新选择文件。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("无法从文件中读取数据或文件格式不正确");
                    }
                }
                Address_Book_Has_Error = false;
                Address_Book_Bling_Error = false;
            }
        }
        /// <summary>
        /// 打开Excel文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Add_ExcelFile(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = ".xlsx";
            dlg.Filter = "Excel Files (*.xlsx)|*.xlsx|Excel Files (*.xls)|*.xls";
            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                openyztfile_path = dlg.FileName;
                (DataTable dataTable, int rowCount) = ReadExcelFile(openyztfile_path);
                if (dataTable != null)
                {
                    DataQuery_vDataBinding(dataTable);
                    if (!Address_Book_Bling_Error)
                    {
                        CountNonEmptyRows(dataTable);
                        CunrrentFileName_Text.Text = System.IO.Path.GetFileName(openyztfile_path);
                    }
                    else
                    {
                        MessageBox.Show("导入的文件不符合通讯录文件要求（最多2列127行），请重新选择文件。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
                else
                {
                    MessageBox.Show("无法读取 Excel 文件。");
                }
                Address_Book_Bling_Error = false;
            }
        }
        /// <summary>
        /// 拖拽Excel/Yzt导入Datagrid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DtgData_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                openyztfile_path = files.FirstOrDefault(); // 获取拖拽的第一个文件路径
                if (openyztfile_path != null)
                {
                    string fileExtension = System.IO.Path.GetExtension(openyztfile_path).ToLower();
                    if (fileExtension == ".xlsx" || fileExtension == ".xls")
                    {
                        (DataTable dataTable, int rowCount) = ReadExcelFile(openyztfile_path);
                        if (dataTable != null)
                        {
                            DataQuery_vDataBinding(dataTable);
                            if (!Address_Book_Bling_Error)
                            {
                                CountNonEmptyRows(dataTable);
                                CunrrentFileName_Text.Text = System.IO.Path.GetFileName(openyztfile_path);
                            }
                            else
                            {
                                MessageBox.Show("导入的文件不符合通讯录文件要求（最多2列127行），请重新选择文件。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                            }
                        }
                        else
                        {
                            MessageBox.Show("无法读取 Excel 文件");
                        }
                    }
                    else if (fileExtension == ".yzt")
                    {
                        (DataTable dataTable, int yztCount) = ReadYztFileToDataTable(openyztfile_path);
                        if (dataTable != null)
                        {
                            DataQuery_vDataBinding(dataTable);//绑定datagrid控件
                            if (!Address_Book_Bling_Error)
                            {
                                CountNonEmptyRows(dataTable);//计算有效行数
                                CunrrentFileName_Text.Text = System.IO.Path.GetFileName(openyztfile_path);
                            }
                            else
                            {
                                MessageBox.Show("导入的文件不符合通讯录文件要求（最多2列127行），请重新选择文件。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                            }
                        }
                        else
                        {
                            MessageBox.Show("无法读取 Yzt 文件");
                        }
                    }
                    else
                    {
                        MessageBox.Show("不支持的文件类型。");
                    }
                    Address_Book_Bling_Error = false;
                }
            }
        }
        /// <summary>
        /// 保存当前文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveFile_Click(object sender, RoutedEventArgs e)
        {
            if (DtgData.ItemsSource != null)
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                string fileExtension = System.IO.Path.GetExtension(openyztfile_path).ToLower();
                if (fileExtension == ".xlsx" || fileExtension == ".xls")
                {
                    saveFileDialog.Filter = "Excel Files (*.xlsx;*.xls)|*.xlsx;*.xls|All files (*.*)|*.*";
                }
                else if (fileExtension == ".yzt")
                {
                    saveFileDialog.Filter = "Yzt Files (*.yzt)|*.yzt|All files (*.*)|*.*";
                }
                else
                {
                    MessageBox.Show("不支持的文件类型!");
                }
                saveFileDialog.FileName = openyztfile_path;
                try
                {
                    DataTable dataTable = ((DataView)DtgData.ItemsSource).ToTable();
                    SaveYztFileFromDataTable(saveFileDialog.FileName, dataTable, DtgData);//读取DataGrid控件中的内容，保存到源文件中
                    MessageBox.Show(saveFileDialog.FileName + "保存成功！");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("保存失败：" + ex.Message);
                }
            }
            else
            {
                MessageBox.Show("没有可保存的数据！");
            }
        }
        /// <summary>
        /// 另存为Yzt文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AgainSaveYztFile_Click(object sender, RoutedEventArgs e)
        {
            if (DtgData.ItemsSource != null)
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Filter = "Yzt Files (*.yzt)|*.yzt|All files (*.*)|*.*";
                if (saveFileDialog.ShowDialog() == true)
                {
                    try
                    {
                        DataTable dataTable = ((DataView)DtgData.ItemsSource).ToTable();
                        SaveYztFileFromDataTable(saveFileDialog.FileName, dataTable, DtgData);//读取DataGrid控件中的内容，保存到源文件中
                        MessageBox.Show("保存成功！");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("保存失败：" + ex.Message);
                    }
                }
            }
            else
            {
                MessageBox.Show("没有可保存的数据！");
            }
        }
        /// <summary>
        /// 另存为Excel文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AgainSaveExcelFile_Click(object sender, RoutedEventArgs e)
        {
            if (DtgData.ItemsSource != null)
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Filter = "Excel Files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
                if (saveFileDialog.ShowDialog() == true)
                {
                    try
                    {
                        DataTable dataTable = ((DataView)DtgData.ItemsSource).ToTable();
                        SaveExcelFileFromDataTable(saveFileDialog.FileName, dataTable);
                        MessageBox.Show("保存成功！");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("保存失败：" + ex.Message);
                    }
                }
            }
            else
            {
                MessageBox.Show("没有可保存的数据！");
            }
        }
        /// <summary>
        /// 关闭文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QuitYztFile_Click(object sender, RoutedEventArgs e)
        {
            if (!IsDataGridModified(openyztfile_path))
            {
                var result = MessageBox.Show("数据有修改，是否保存当前数据？", "提示", MessageBoxButton.YesNoCancel);
                if (result == MessageBoxResult.Yes)
                {
                    // 保存修改
                    SaveFile_Click(sender, e);
                }
                else if (result == MessageBoxResult.No)
                {
                    // 清空 DataGrid 中的内容
                    DtgData.DataContext = null;
                    CommunicateNumber_Text.Clear();
                    CunrrentFileName_Text.Clear();
                    CheckFile_Profess.Value = 0;
                }
                else
                {
                    return;
                }
            }
            else
            {
                // 清空 DataGrid 中的内容
                DtgData.DataContext = null;
                CommunicateNumber_Text.Clear();
                CunrrentFileName_Text.Clear();
                CheckFile_Profess.Value = 0;
            }
        }

        #endregion

        #region -- 生成
        /// <summary>
        /// 将DataGrid表格中数据经过筛选生成Yzt文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GenerateYzt_Click(object sender, RoutedEventArgs e)
        {
            bool check_result = false;
            if (DtgData.ItemsSource != null)
            {
                if (Check_ExceptGB2312(DtgData))
                {
                    check_result = true;
                }
                if (Check_PhoneNumberContent(DtgData))
                {
                    check_result = true;
                }
                if (Check_Beyond13Bytes(DtgData))
                {
                    check_result = true;
                }
                if (AddressBook_Number > 127)
                {
                    check_result = true;
                }
                if (!check_result)
                {
                    SaveFileDialog saveFileDialog = new SaveFileDialog();
                    saveFileDialog.Filter = "Yzt Files (*.yzt)|*.yzt|All files (*.*)|*.*";
                    if (saveFileDialog.ShowDialog() == true)
                    {
                        try
                        {
                            DataTable dataTable = ((DataView)DtgData.ItemsSource).ToTable();
                            SaveYztFileFromDataTable(saveFileDialog.FileName, dataTable, DtgData);//
                            MessageBox.Show("生成成功！");
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("生成失败：" + ex.Message);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("当前文件内容存在GB2312以外的字符或数据内容超过127行或地址列和分机号列内容不符合规范要求，请修改！", "提示");
                    check_result = false;
                }
            }
            else
            {
                MessageBox.Show("没有可生成的数据！");
            }
        }
        /// <summary>
        /// 将DataGrid表格中数据经过筛选生成到Excel中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GenerateExcel_Click(object sender, RoutedEventArgs e)
        {
            bool check_result = false;
            if (DtgData.ItemsSource != null)
            {
                if (Check_ExceptGB2312(DtgData))
                {
                    check_result = true;
                }
                if (Check_PhoneNumberContent(DtgData))
                {
                    check_result = true;
                }
                if (Check_Beyond13Bytes(DtgData))
                {
                    check_result = true;
                }
                if (AddressBook_Number > 127)
                {
                    check_result = true;
                }
                if (!check_result)
                {
                    SaveFileDialog saveFileDialog = new SaveFileDialog();
                    saveFileDialog.Filter = "Excel Files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
                    if (saveFileDialog.ShowDialog() == true)
                    {
                        try
                        {
                            DataTable dataTable = ((DataView)DtgData.ItemsSource).ToTable();
                            SaveExcelFileFromDataTable(saveFileDialog.FileName, dataTable);
                            MessageBox.Show("生成成功！");
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("生成失败：" + ex.Message);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("当前文件内容存在GB2312以外的字符或数据内容超过127行或地址列和分机号列内容不符合规范要求，请修改！", "提示");
                    check_result = false;
                }
            }
            else
            {
                MessageBox.Show("没有可生成的数据！");
            }
        }
        #endregion

        #region -- 帮助
        /// <summary>
        /// 测试地址列字符要求
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void CheckAddressLenth_Click(object sender, RoutedEventArgs e)
        {
            CheckFile_Profess.Visibility = Visibility.Visible; // 显示进度条
            CheckFile_Profess.Value = 0;
            await Task.Run(() =>
            {
                double totalCells = DtgData.Columns.Count;
                double processedCells = 0;

                foreach (var item in DtgData.Items)
                {
                    if (item is DataRowView rowView)
                    {
                        Dispatcher.Invoke(() =>
                        {
                            var cellContent = rowView.Row.ItemArray[0].ToString(); // 地址列的数据
                                                                                   // 计算字符串的实际字符数，一个汉字算作两个字符
                            int characterCount = GetCharacterCount(cellContent);
                            if (characterCount > 13)
                            {
                                // 获取地址列单元格的 TextBlock 控件
                                var cell = DtgData.Columns[0].GetCellContent(rowView) as TextBlock;
                                if (cell != null)
                                {
                                    cell.Foreground = Brushes.Blue; // 将单元格内容标记为蓝色
                                }
                            }
                        });
                        processedCells++;
                        // 计算并更新进度条
                        double progress = processedCells / totalCells * 100;
                        Dispatcher.Invoke(() =>
                        {
                            CheckFile_Profess.Value = progress;
                        });
                    }
                }
            });
        }
        /// <summary>
        /// 检测CB2312测试功能
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void Check_GB2312Words(object sender, RoutedEventArgs e)
        {
            PublicFunction publicfunction = new PublicFunction();
            CheckFile_Profess.Visibility = Visibility.Visible; // 显示进度条
            CheckFile_Profess.Value = 0;
            await Task.Run(() =>
            {
                double totalCells = DtgData.Items.Count * DtgData.Columns.Count;
                double currentCell = 0;
                foreach (var item in DtgData.Items)
                {
                    if (item is DataRowView rowView)
                    {
                        foreach (DataGridColumn column in DtgData.Columns)
                        {
                            Dispatcher.Invoke(() =>
                            {
                                var cellContent = column.GetCellContent(rowView);
                                if (cellContent is TextBlock textBlock)
                                {
                                    string text = textBlock.Text;
                                    char[] textcontent = text.ToCharArray();
                                    string[] textstring = new string[textcontent.Length];
                                    for (int i = 0; i < textcontent.Length; i++)
                                    {
                                        textstring[i] = textcontent[i].ToString();
                                        if (!publicfunction.IsGB2312(textstring[i], true))
                                            textBlock.Foreground = Brushes.Red; // 将字符标记为红;
                                    }
                                }
                            });
                            currentCell++;
                            double progress = currentCell / totalCells * 100;
                            Dispatcher.Invoke(() =>
                            {
                                CheckFile_Profess.Value = progress; // 更新进度条
                            });
                        }
                    }
                }
            });
        }
        /// <summary>
        /// 检测分机号列字符要求
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void Check_PhoneNunber(object sender, RoutedEventArgs e)
        {
            HashSet<int> distinctPhoneNumbers = new HashSet<int>();
            CheckFile_Profess.Visibility = Visibility.Visible; // 显示进度条
            CheckFile_Profess.Value = 0;

            await Task.Run(() =>
            {
                double totalCells = DtgData.Columns.Count;
                double processedCells = 0;
                foreach (var item in DtgData.Items)
                {
                    if (item is DataRowView rowView)
                    {
                        var address = rowView.Row.ItemArray[1].ToString().Trim();
                        if (address.Length == 0)
                        {
                            continue;
                        }
                        //检查是否为数字，且数字是否在1~127直间
                        if (int.TryParse(address, out int number) && (number >= 1 && number <= 127))
                        {
                            //检查是否有重复
                            if (!distinctPhoneNumbers.Add(number))
                            {
                                Dispatcher.Invoke(() =>
                                {
                                    var cell = DtgData.Columns[1].GetCellContent(rowView) as TextBlock;
                                    if (cell != null)
                                    {
                                        cell.Foreground = Brushes.Orange; // 将包含重复分机号的单元格字体标记
                                    }
                                });
                            }
                        }
                        else
                        {
                            Dispatcher.Invoke(() =>
                            {
                                var cell = DtgData.Columns[1].GetCellContent(rowView) as TextBlock;
                                if (cell != null)
                                {
                                    cell.Foreground = Brushes.Green; // 将包含非法字符或超出范围数字的单元格标记
                                }
                            });
                        }
                        Dispatcher.Invoke(() =>
                        {
                            processedCells++;
                            double progress = processedCells / totalCells * 100;
                            CheckFile_Profess.Value = progress;
                        });
                    }
                }
            });
        }
        /// <summary>
        /// 软件使用手册
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_OpenExpriseBook(object sender, RoutedEventArgs e)
        {
            // 获取执行文件所在目录
            string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
            // 拼接相对路径
            string exprisePath = System.IO.Path.Combine(currentDirectory, "软件使用说明.docx");
            // 检查文件是否存在
            if (File.Exists(exprisePath))
            {
                // 启动进程打开文件
                var startfile = new ProcessStartInfo { FileName = exprisePath, UseShellExecute = true };
                Process.Start(startfile);
            }
            else
            {
                // 文件不存在，处理错误或提供用户反馈
                MessageBox.Show("找不到操作说明文档。");
            }
        }
        #endregion

        #endregion


        #region -- 子程序
        /// <summary>
        /// 将字符转为GB2312方法
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        private static char[] ConvertToGB2312(string original)
        {
            Encoding gb2312Encoding = Encoding.GetEncoding("gb2312");
            byte[] bytes = gb2312Encoding.GetBytes(original);
            char[] chars = gb2312Encoding.GetChars(bytes);
            //return gb2312Encoding.GetString(bytes);
            return chars;
        }
        /// <summary>
        /// 编辑单元格事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DtgData_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
        {
            var dataGrid = sender as DataGrid;
            var editedRow = e.Row.Item as DataRowView;
            var columnIndex = e.Column.DisplayIndex;

            // 只有在编辑第一列时才更新非空行计数
            if (columnIndex == 0)
            {
                // 获取编辑前的第一列值
                string oldValue = editedRow.Row[0]?.ToString()?.Trim();

                string editedCellValue = e.EditingElement is TextBox textBox ? textBox.Text?.Trim() : null;
                editedRow.Row[columnIndex] = editedCellValue;

                bool wasFirstColumnNonEmptyBeforeEdit = !string.IsNullOrEmpty(oldValue) && oldValue.Length > 0;
                bool isFirstColumnNonEmptyAfterEdit = !string.IsNullOrEmpty(editedCellValue) && editedCellValue.Length > 0;

                if (isFirstColumnNonEmptyAfterEdit && !wasFirstColumnNonEmptyBeforeEdit)
                {
                    AddressBook_Number++;
                }
                else if (!isFirstColumnNonEmptyAfterEdit && wasFirstColumnNonEmptyBeforeEdit)
                {
                    AddressBook_Number--;
                }

                CommunicateNumber_Text.Text = AddressBook_Number.ToString();
            }
        }
        /// <summary>
        /// 计算非空行数
        /// </summary>
        /// <param name="dataTable"></param>
        private void CountNonEmptyRows(DataTable dataTable)
        {
            AddressBook_Number = 0;
            foreach (DataRow row in dataTable.Rows)
            {
                bool hasValidData = false;
                foreach (var item in row.ItemArray)
                {
                    string cellValue = item?.ToString()?.Trim(); // 先移除两端空白字符
                    if (!string.IsNullOrEmpty(cellValue) && cellValue.Trim().Length > 0)
                    {
                        hasValidData = true;
                        break;
                    }
                }
                if (hasValidData)
                {
                    AddressBook_Number++;

                }
            }
            CommunicateNumber_Text.Text = AddressBook_Number.ToString();
        }
        /// <summary>
        /// 将数据内容绑定到datagrid控件中
        /// </summary>
        /// <param name="dataTable"></param>
        private void DataQuery_vDataBinding(DataTable dataTable)
        {
            if (dataTable != null && dataTable.Columns.Count > 0)
            {
                // 检查列数是否超过3列
                if (dataTable.Columns.Count <= 2)
                {
                    // 检查行数是否超过127行
                    if (dataTable.Rows.Count <= 127)
                    {
                        while (dataTable.Rows.Count < 126)
                        {
                            dataTable.Rows.Add(new object[dataTable.Columns.Count]); // 添加一行空行
                        }
                        DtgData.DataContext = dataTable;
                    }
                    else
                    {
                        Address_Book_Bling_Error = true;
                        // 行数超过127，绑定出错
                    }
                }
                else
                {
                    Address_Book_Bling_Error = true;
                    // 超过2列，绑定出错
                }
            }
        }
        /// <summary>
        /// 将DataGrid控件中的内容保存到yzt文件中
        /// </summary>
        /// <param name="filePath">保存的文件路径</param>
        /// <param name="dataTable">保存修改后的数据内容</param>
        /// <param name="dataGrid">DataGrid控件</param>
        private void SaveYztFileFromDataTable(string filePath, DataTable dataTable, DataGrid dataGrid)
        {
            using (StreamWriter writer = new StreamWriter(filePath, false, Encoding.GetEncoding("GB2312")))
            {
                int columnCount = dataTable.Columns.Count;
                // 写入数据
                foreach (DataRow row in dataTable.Rows)
                {
                    for (int i = 0; i < columnCount; i++)
                    {
                        writer.Write(row[i].ToString());
                        if (i < columnCount - 1) // 如果不是最后一列，则添加制表符
                        {
                            writer.Write("\t");
                        }
                    }
                    writer.WriteLine();
                }
            }
        }
        /// <summary>
        /// 读取yzt文件内容
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private (DataTable dataTable, int rowCount) ReadYztFileToDataTable(string filePath)
        {
            DataTable dataTable = new DataTable();
            int rowCount = 0;
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            // 手动指定列名，这里假设列名就是"地址"和"分机号"
            dataTable.Columns.Add("地址");
            dataTable.Columns.Add("分机号");
            using (StreamReader reader = new StreamReader(filePath, Encoding.GetEncoding("GB2312")))
            {
                while (!reader.EndOfStream)
                {
                    string dataLine = reader.ReadLine();
                    if (string.IsNullOrEmpty(dataLine)) continue;

                    string[] fields = dataLine.Split('\t');

                    if (fields.Length == dataTable.Columns.Count)
                    {
                        DataRow newRow = dataTable.NewRow();
                        newRow["地址"] = fields[0].Trim();
                        newRow["分机号"] = fields[1].Trim();
                        dataTable.Rows.Add(newRow);
                        rowCount++;
                    }
                    else
                    {
                        // 如果不匹配且已有列，可以选择忽略该行数据或者进行其他处理
                        // 这里选择忽略该行数据
                        continue;
                    }
                }
            }
            return (dataTable, rowCount);
        }
        /// <summary>
        /// 检测DataGrid控件中是否有内容修改
        /// </summary>
        /// <param name="filePath">刚开始的文件路径</param>
        /// <returns></returns>
        private bool IsDataGridModified(string filePath)
        {
            bool result = false;
            // 获取 DataGrid 中的数据源
            var dataView = DtgData.ItemsSource as DataView;
            if (dataView == null)
            {
                return false; // 如果数据源为空，认为没有修改
            }
            if (System.IO.Path.GetExtension(filePath) == ".xlsx" || System.IO.Path.GetExtension(filePath) == ".xls")
            {
                // 获取 DataGrid 中的原始数据源（假设在加载数据时保存了原始数据源）
                (DataTable originalDataTable, int rowCount) = ReadExcelFile(filePath); // 此处需要根据Excel获取原始数据源
                result = DataTableEquals(dataView.ToTable(), originalDataTable);
            }
            else if (System.IO.Path.GetExtension(filePath) == ".yzt")
            {
                (DataTable originalDataTable, int rowCount) = ReadYztFileToDataTable(filePath); // 此处需要根据Yzt获取原始数据源                                                                     
                result = DataTableEquals(dataView.ToTable(), originalDataTable);
            }
            return result;
        }
        /// <summary>
        /// 比较DataGrid当前内容和刚打开时的内容
        /// </summary>
        /// <param name="table1">当前的表</param>
        /// <param name="table2">开始的表</param>
        /// <returns></returns>
        private bool DataTableEquals(DataTable table1, DataTable table2)
        {
            // 检查行数和列数是否相同
            if (table1.Rows.Count != table2.Rows.Count || table1.Columns.Count != table2.Columns.Count)
            {
                return false; // 行数或列数不同，认为不相同
            }

            for (int i = 0; i < table1.Rows.Count; i++)
            {
                for (int j = 0; j < table1.Columns.Count; j++)
                {
                    if (!Equals(table1.Rows[i][j], table2.Rows[i][j]))
                    {
                        return false; // 值不同，认为不相同
                    }
                }
            }
            // 所有值都相同，认为相同
            return true;
        }
        /// <summary>
        /// 读取Excel文件中的数据内容
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private (DataTable dataTable, int rowCount) ReadExcelFile(string filePath)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("地址", typeof(string));
            dt.Columns.Add("分机号", typeof(string));
            int rowCount = 0;
            try
            {
                using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
                {
                    IWorkbook workbook = WorkbookFactory.Create(stream);
                    ISheet sheet = workbook.GetSheetAt(0);

                    // 跳过表头行（如果存在的话）
                    int headerRowIndex = sheet.FirstRowNum;
                    IRow headerRow = sheet.GetRow(headerRowIndex);
                    if (headerRow != null)
                    {
                        headerRowIndex++;
                    }

                    // 遍历工作表的行
                    for (int rowIndex = 1; rowIndex <= sheet.LastRowNum; rowIndex++)
                    {
                        IRow row = sheet.GetRow(rowIndex);

                        if (row != null && row.LastCellNum >= 2)
                        {
                            DataRow newRow = dt.NewRow();
                            newRow["地址"] = row.GetCell(0)?.ToString()?.Trim();
                            newRow["分机号"] = row.GetCell(1)?.ToString()?.Trim();

                            dt.Rows.Add(newRow);
                            rowCount++;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取 Excel 文件时出现错误：" + ex.Message);
                dt = null;
                rowCount = 0;
            }
            return (dt, rowCount);
        }
        /// <summary>
        /// 将DataGrid中的数据保存到Excel文件中
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="dataTable"></param>
        private void SaveExcelFileFromDataTable(string filePath, DataTable dataTable)
        {
            XSSFWorkbook workbook = new XSSFWorkbook();
            ISheet sheet = workbook.CreateSheet("Sheet1");
            // 写入表头
            // 写入固定的表头名称
            IRow headerRow = sheet.CreateRow(0);
            headerRow.CreateCell(0).SetCellValue("地址");
            headerRow.CreateCell(1).SetCellValue("分机号");
            // 写入数据
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                IRow dataRow = sheet.CreateRow(i+1);
                for (int j = 0; j < dataTable.Columns.Count; j++)
                {
                    dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());
                }
            }
            // 保存文件
            using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(fs);
            }
        }
        /// <summary>
        /// 检测datagrid控件中是否存在GB2312以外的字符
        /// </summary>
        /// <param name="datagrid">控件参数</param>
        /// <returns>返回结果</returns>
        private bool Check_ExceptGB2312(DataGrid datagrid)
        {
            bool result = false;
            PublicFunction publicfunction = new PublicFunction();
            foreach (var item in datagrid.Items)
            {
                if (item is DataRowView rowView)
                {
                    foreach (DataGridColumn column in datagrid.Columns)
                    {
                        Dispatcher.Invoke(() =>
                        {
                            var cellContent = column.GetCellContent(rowView);
                            if (cellContent is TextBlock textBlock)
                            {
                                string text = textBlock.Text;
                                char[] textcontent = text.ToCharArray();
                                string[] textstring = new string[textcontent.Length];
                                for (int i = 0; i < textcontent.Length; i++)
                                {
                                    textstring[i] = textcontent[i].ToString();
                                    if (!publicfunction.IsGB2312(textstring[i], true))
                                    {
                                        textBlock.Foreground = Brushes.Red; // 将字符标记为红;
                                        result = true;
                                    }
                                    else
                                    {
                                        result = false;
                                    }
                                }
                            }
                        });
                    }
                }
            }
            return result;
        }
        /// <summary>
        /// 检测datagrid控件中地址列是否存在超过13个字节的字符
        /// </summary>
        /// <param name="datagrid">控件参数</param>
        /// <returns>返回结果</returns>
        private bool Check_Beyond13Bytes(DataGrid datagrid)
        {
            bool result = false;
            foreach (var item in datagrid.Items)
            {
                if (item is DataRowView rowView)
                {
                    var cellContent = rowView.Row.ItemArray[0].ToString(); // 地址列的数据
                    // 计算字符串的实际字符数，一个汉字算作两个字符
                    int characterCount = GetCharacterCount(cellContent);
                    if (characterCount > 13)
                    {
                        // 获取地址列单元格的 TextBlock 控件
                        var cell = datagrid.Columns[0].GetCellContent(rowView) as TextBlock;
                        if (cell != null)
                        {
                            cell.Foreground = Brushes.Blue; // 将单元格内容标记为蓝色
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                }
            }
            return result;
        }
        /// <summary>
        /// 新增辅助方法，用于计算字符串的实际字符数
        /// </summary>
        /// <param name="input">输入内容</param>
        /// <returns></returns>
        private static int GetCharacterCount(string input)
        {
            int count = 0;
            foreach (char c in input.Normalize(NormalizationForm.FormD))
            {
                if (IsChineseCharacter(c))
                {
                    count += 2;
                }
                else
                {
                    count++;
                }
            }
            return count;
        }
        /// <summary>
        /// 新增辅助方法，判断字符是否为汉字
        /// </summary>
        /// <param name="c">输入字符</param>
        /// <returns></returns>
        private static bool IsChineseCharacter(char c)
        {
            // 根据汉字在Unicode中的范围进行判断
            return c >= '\u4E00' && c <= '\u9FA5'; // 汉字基本区
        }
        /// <summary>
        /// 检测分机号列是否在1~127范围内
        /// </summary>
        /// <param name="datagrid">控件</param>
        /// <returns></returns>
        private bool Check_PhoneNumberContent(DataGrid datagrid)
        {
            bool result = false;
            HashSet<int> distinctPhoneNumbers = new HashSet<int>();
            foreach (var item in datagrid.Items)
            {
                if (item is DataRowView rowView)
                {
                    var address = rowView.Row.ItemArray[1].ToString(); // 分机号列的数据
                                                                       // 检查单元格内容是否为空格
                    if (address.Trim().Length == 0)
                    {
                        // 如果为空格，跳过此次循环
                        continue;
                    }
                    // 直接尝试将整行内容转换为数字，并检查是否在1到127之间
                    if (int.TryParse(address, out int number) && (number >= 1 && number <= 126))
                    {
                        // 检查分机号是否重复
                        if (!distinctPhoneNumbers.Add(number))
                        {
                            // 获取地址列单元格的 TextBlock 控件
                            var cell = datagrid.Columns[1].GetCellContent(rowView) as TextBlock;
                            if (cell != null)
                            {
                                cell.Foreground = Brushes.Orange; // 将包含重复分机号的单元格字体标记
                                result = true; // 发现重复，设置结果为true
                            }
                        }
                    }
                    else
                    {
                        // 获取地址列单元格的 TextBlock 控件
                        var cell = datagrid.Columns[1].GetCellContent(rowView) as TextBlock;
                        if (cell != null)
                        {
                            cell.Foreground = Brushes.Green; // 将包含非法字符或超出范围数字的单元格标记
                            result = true;
                        }
                    }
                }
            }
            return result;
        }
        #endregion

        #region -- 窗口关闭
        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            RoutedEventArgs f = new RoutedEventArgs();
            if (DtgData.ItemsSource != null)
            {
                if (!IsDataGridModified(openyztfile_path))
                {
                    MessageBoxResult result = MessageBox.Show("是否要保存数据？", "提示", MessageBoxButton.YesNoCancel);
                    if (result == MessageBoxResult.Yes)
                    {
                        SaveFile_Click(sender, f);
                    }
                    else if (result == MessageBoxResult.Cancel)
                    {
                        e.Cancel = true; // 取消关闭操作
                    }
                }
                else
                {
                    Application.Current.Shutdown();
                }
            }
            else
            {
                Application.Current.Shutdown();
            }
        }

        private void MainWindow_Closed(object sender, EventArgs e)
        {
            // 退出软件
            Application.Current.Shutdown();
        }










        #endregion

        
    }
}
